<?php
/**
 *  WB_BaseClass class
 *  Base class for all objects.
 *
 *  @author Jean-Lou Dupont
 *  @version @@package-version@@
 */

//{{include
//include}}

 abstract class WB_BaseClass
 {
 	/**
 	 * Objects currently used
 	 * @private
 	 */
 	static $_objects = array();
	
	/**
	 * The parameters assigned to this object instance
	 */
	var $params = null;

	/**
	 * Array of references to registered objects.
	 * @private
	 */
	static $_keys = array();	
		
	/**
	 * Indicator of change to the object's state
	 * @private
	 */
	var $_changeStatus = null;		
	
	/**
	 * Indicator that the class
	 * should be handled through a 
	 * singleton pattern.
	 * @private
	 */
	static $_singletonStatus = null;
	
	/**
	 * Singleton pattern 
	 * @private
	 */
	static $_singletonInstance = null;
	
 	/**
 	 * Constructor
 	 * 
 	 * @param $class class of this object instance
 	 * @param $params parameters of this object
 	 */
 	public function __construct( $params = null )
	{
		// useful for the persistence functionality
		$this->_changeStatus = false;
		
		$class = get_class( $this );
		
		self::$_objects[ $class ][] = $this;
		$this->params = $params;
		
		// keep a tab on this object if we are
		// passed a key to it.
		if (isset( $params ) )
			if (isset( $params[ 'key' ]))
				self::$_keys[ $params[ 'key' ] ] = $this;
	}
	
	/**
	 * Returns the value of the configuration parameter
	 * specified by $key.
	 * 
	 * @return mixed value
	 * @param $key Object
	 */
	public function getParam( $key )
	{
		return @$this->params[ $key ];
	}
	/**
	 * throwFromException
	 * Enables re-throwning an exception under the current
	 * class. The message & code parameters are preserved.
	 * 
	 * @return 
	 * @param $e Object
	 */
 	protected function throwFromException( $e )
	{
		$this->throwException( $e->getMessage(), $e->getCode() );
	}
	/**
	 * throwException
	 * Enables throwing an exception under the
	 * current class (i.e. instead of the default 'Exception class)
	 * 
	 * @return 
	 * @param $msg Object[optional]
	 * @param $code Object[optional]
	 */
	protected function throwException( $msg = null, $code = 0 )
	{
		$class = get_class( $this );
		
		// strip off 'WB_' if present
		$classPath = str_replace( 'WB_', '', $class );
		
		$path  = $this->getClassPath().'/'.$classPath.'_Exception.php';
		$class_exception = $class.'_Exception';
		
		require_once $path;
		throw new $class_exception( $msg, $code );
	}
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	// Abstract Interface
	// NOTE: must be implemented in derived classes
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	/**
	 * getClassPath
	 * 
	 * @return string relative/absolute class path.
	 */
	abstract public function getClassPath();

	/**
	 * getClassVersion
	 * 
	 * @return string version
	 */
	abstract public function getClassVersion();

	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	// GENERIC Get/Set
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	/**
	 * Generic Get method
	 * 
	 * @return $value
	 * @param $key string
	 */	
	public function __get( $key )
	{
		return @$this->$key;
	}
	/**
	 * Generic Set method
	 * 
	 * @return $this
	 * @param $key string
	 * @param $value mixed
	 */
	public function __set( $key, $value )
	{
		@$this->$key = $value;
		
		// useful for the persistence functionality
		$this->_changeStatus = true;
		
		return $this;
	}
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	// Singleton HELPER Functionality
	// 
	// The derived classes that implement the WB_Singleton_IF interface
	// can use these functions.
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	/**
	 * Returns a singleton instance of the $classe
	 * 
	 * @return $object
	 * @param $instance Object
	 * @param $classe Object
	 * @param $params Object[optional]
	 */
	protected static function _handleSingleton( &$instance, $classe, $params = null )
	{
		if ( !is_null( $instance ) )
			return $instance;
			
		$instance = new $classe( $params );
		
		return $instance;
	}

	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	// Persistence Functionality
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	/**
	 * Sets the change status flag.
	 * 
	 * @return $this
	 * @param $status boolean[optional]
	 */
	public function setChangeStatus( $status = true /*changed*/ )
	{
		$this->_changeStatus = $status;
		return $this;
	}
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	// OBJECT POOL INTERFACE
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	/**
	 * Retrieves an object from the pool.
	 * 
	 * @return 
	 * @param $key Object
	 */
	public static function retrieve( $key )
	{
		return (isset( self::$_keys[ $key ] )) ? self::$_keys[ $key ]:null;
	}
	
 } // end class
